﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

using System.ComponentModel;
using System.Runtime.InteropServices;

using BYTE = System.Byte;
using WORD = System.Int16;
using DWORD = System.Int32;

namespace DecompressHeightMap
{
	//	Block data compress flags
	public enum flags : byte
	{
		T2BKCOMP_COL_ZIP = 0x01,        //	ZIP compression for color
										//	T2BKCOMP_COL_16B	= 0x02,		//	16-bit compression for color
		T2BKCOMP_HEI_ZIP = 0x04,        //	ZIP compression for vertex height
		T2BKCOMP_HEI_INC = 0x08,        //	Incremental compression for vertex height
		T2BKCOMP_NOR_ZIP = 0x10,        //	ZIP compression for normal
		T2BKCOMP_NOR_DEG = 0x20,        //	Degree compression for normal
		T2BKCOMP_HEI_INC2 = 0x40,       //	Incremental compression 2 for vertex height
	};

	//	Terrain file ID and cersion
	//[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
	[StructLayout(LayoutKind.Explicit, Size = 8, CharSet = CharSet.Ansi)]
	public struct TRN2FILEIDVER
    {
		[FieldOffset(0)] public DWORD dwIdentify;       //	Identity, must be TRN2FILE_IDENTIFY
		[FieldOffset(4)] public DWORD dwVersion;        //	Version, must be TRN2FILE_VERSION
    };

	//[MarshalAs(UnmanagedType.R8)]
	//	Block data file header, T2BKFILE_VERSION < 2
	[StructLayout(LayoutKind.Explicit, Size = 4, CharSet = CharSet.Ansi)]
	public struct T2BKFILEHEADER
    {
		[FieldOffset(0)] public int iNumBlock;      //	Number of block
    };

	//	Block data file header, T2BKFILE_VERSION >= 2
	[StructLayout(LayoutKind.Explicit, Size = 5, CharSet = CharSet.Ansi)]
	public struct T2BKFILEHEADER2
    {
		[FieldOffset(0)] public int iNumBlock;      //	Number of block
		[FieldOffset(4)] public bool bCompressed;   //	Data compression flag
    };

	//	Block data file header, T2BKFILE_VERSION >= 5
	[StructLayout(LayoutKind.Explicit, Size = 8, CharSet = CharSet.Ansi)]
	public struct T2BKFILEHEADER5
    {
		[FieldOffset(0)] public int iNumBlock;      //	Number of block
		[FieldOffset(4)] public DWORD byCompressed;  //	Compression flag
    };

	//	Block information
	[StructLayout(LayoutKind.Explicit, Size = 16, CharSet = CharSet.Ansi)]
	public struct T2BKFILEBLOCK
	{
		[FieldOffset(0)] public int iMaskArea;      //	Index of mask area this block blongs to
		[FieldOffset(4)] public WORD iRowInTrn;     //	Row of this block in whole terrain
		[FieldOffset(6)] public WORD iColInTrn;     //	Column of this block in whole terrain
		[FieldOffset(8)] public float fLODScale;        //	LOD scale factor
		[FieldOffset(12)] public DWORD dwLayerFlags; //	Effect layer flags
	};

	//	Block information, T2BKFILE_VERSION >= 2
	[StructLayout(LayoutKind.Explicit, Size = 18, CharSet = CharSet.Ansi)]
	public struct T2BKFILEBLOCK2
	{
		[FieldOffset(0)] public int iMaskArea;      //	Index of mask area this block blongs to
		[FieldOffset(4)] public WORD iRowInTrn;     //	Row of this block in whole terrain
		[FieldOffset(6)] public WORD iColInTrn;     //	Column of this block in whole terrain
		[FieldOffset(8)] public float fLODScale;        //	LOD scale factor
		[FieldOffset(12)] public DWORD dwLayerFlags; //	Effect layer flags
		[FieldOffset(14)] public DWORD dwHeiSize;        //	Height data size
		[FieldOffset(16)] public DWORD dwNormalSize; //	Normal data size
	};

	//	Block information, T2BKFILE_VERSION >= 3
	[StructLayout(LayoutKind.Explicit, Size = 20, CharSet = CharSet.Ansi)]
	public struct T2BKFILEBLOCK3
	{
		[FieldOffset(0)] public int iMaskArea;      //	Index of mask area this block blongs to
		[FieldOffset(4)] public WORD iRowInTrn;     //	Row of this block in whole terrain
		[FieldOffset(6)] public WORD iColInTrn;     //	Column of this block in whole terrain
		[FieldOffset(8)] public float fLODScale;        //	LOD scale factor
		[FieldOffset(12)] public DWORD dwLayerFlags; //	Effect layer flags
		[FieldOffset(14)] public DWORD dwHeiSize;        //	Height data size
		[FieldOffset(16)] public DWORD dwNormalSize; //	Normal data size
		[FieldOffset(18)] public DWORD dwDiffSize;       //	Diffuse data size
	};

	//	Block information, T2BKFILE_VERSION >= 4
	[StructLayout(LayoutKind.Explicit, Size = 22, CharSet = CharSet.Ansi)]
	public struct T2BKFILEBLOCK4
	{
		[FieldOffset(0)] public int iMaskArea;      //	Index of mask area this block blongs to
		[FieldOffset(4)] public WORD iRowInTrn;     //	Row of this block in whole terrain
		[FieldOffset(6)] public WORD iColInTrn;     //	Column of this block in whole terrain
		[FieldOffset(8)] public float fLODScale;        //	LOD scale factor
		[FieldOffset(12)] public DWORD dwLayerFlags; //	Effect layer flags
		[FieldOffset(14)] public DWORD dwHeiSize;        //	Height data size
		[FieldOffset(16)] public DWORD dwNormalSize; //	Normal data size
		[FieldOffset(18)] public DWORD dwDiffSize;       //	Diffuse (day light) data size
		[FieldOffset(20)] public DWORD dwDiffSize1;  //	Diffuse (night light) data size
	};

	//	Block information, T2BKFILE_VERSION >= 6
	[StructLayout(LayoutKind.Explicit, Size = 24, CharSet = CharSet.Ansi)]
	public struct T2BKFILEBLOCK6
	{
		[FieldOffset(0)] public int iMaskArea;      //	Index of mask area this block blongs to
		[FieldOffset(4)] public WORD iRowInTrn;     //	Row of this block in whole terrain
		[FieldOffset(6)] public WORD iColInTrn;     //	Column of this block in whole terrain
		[FieldOffset(8)] public float fLODScale;        //	LOD scale factor
		[FieldOffset(12)] public DWORD dwLayerFlags; //	Effect layer flags
		[FieldOffset(14)] public DWORD dwHeiSize;        //	Height data size
		[FieldOffset(16)] public DWORD dwNormalSize; //	Normal data size
		[FieldOffset(18)] public DWORD dwDiffSize;       //	Diffuse (day light) data size
		[FieldOffset(20)] public DWORD dwDiffSize1;  //	Diffuse (night light) data size
		[FieldOffset(22)] public DWORD dwBlkFlags;       /*  
								dwBlkFlags & T2BKFLAG_NORENDER		The whole block is not rendered
								dwBlkFlags & T2BKFLAG_NOTRACE		The whole block is out of RayTrace
								dwBlkFlags & T2BKFLAG_NOPOSHEIGHT	The whole block is unable to GetPosHeight
							*/
		//char pHeiData[dwHeiSize];
		//char pNormalData[dwNormalSize];
		//char pHeiData2[dwDiffSize];
		//char pNormalData2[dwDiffSize1];
	};

	class Terrain
    {
    }
}
